import { doLoginApi, doLogoutApi, getUserInfoApi } from '@/api/sys/user'
import { PageEnum } from '@/constants'
import { isArray } from '@/utils'
import { pinia, useAuthStore, useLockStore, useMenuStore, useTagStore } from '@/store'
import { usePage } from '@/hooks'

export const useUserStore = defineStore(
	'user',
	() => {
		const userInfo = ref<StoreType.UserInfo | null>(null)
		const accessToken = ref<string | null>(null)
		const userRoles = ref<string[]>([])
		const sessionTimeout = ref<boolean>(false)
		const lastUpdateTime = ref<number>(0)
		const setAccessToken = (info: string | null) => {
			accessToken.value = info ? info : null
		}
		const setRoles = (data: string[]) => {
			userRoles.value = data
		}
		const setUserInfo = (info: StoreType.UserInfo | null) => {
			userInfo.value = info
			lastUpdateTime.value = new Date().getTime()
		}
		const setSessionTimeout = (flag: boolean) => {
			sessionTimeout.value = flag
		}
		const resetUser = () => {
			userInfo.value = null
			accessToken.value = null
			userRoles.value = []
			sessionTimeout.value = false
		}

		const { routerGo, routerPush } = usePage(false)
		//登录
		const login = async function (
			params: ApiType.LoginParams & {
				goHome?: boolean
				mode?: AxiosType.ErrorMessageMode
			}
		): Promise<StoreType.UserInfo | null> {
			try {
				const { goHome = true, mode, ...loginParams } = params

				const { access_token } = await doLoginApi(loginParams, mode)
				// save token
				setAccessToken(access_token)
				if (!accessToken) return null
				const userInfo = await getUserInfoAction()
				if (goHome) await routerGo(PageEnum.BASE_HOME, true)
				return userInfo
			} catch (error) {
				return Promise.reject(error)
			}
		}

		//获取用户信息
		const getUserInfoAction = async function (): Promise<StoreType.UserInfo | null> {
			if (!accessToken) return null
			const userInfo = (await getUserInfoApi()) as unknown as StoreType.UserInfo
			const { roles = [] } = userInfo
			if (isArray(roles)) {
				userRoles.value = roles.map((item) => item.value) as unknown as string[]
			} else {
				userInfo.roles = []
				userRoles.value = []
			}
			setUserInfo(userInfo)
			return userInfo
		}

		const afterLoginAction = async function (goHome?: boolean): Promise<StoreType.UserInfo | null> {
			if (!accessToken) {
				return null
			}
			const userInfo = await getUserInfoAction()

			if (sessionTimeout) {
				setSessionTimeout(false)
			} else {
				goHome && (await routerGo(userInfo?.homePath || PageEnum.BASE_HOME), true)
			}
			return userInfo
		}
		const logout = async function (goLogin = false) {
			if (accessToken) {
				try {
					await doLogoutApi()
				} catch (error: any) {
					console.log('logout error:' + error.toString())
				}
			}
			const { resetLockInfo } = useLockStore()
			const { resetMenu } = useMenuStore()
			const { resetAuth } = useAuthStore()
			const { resetTags } = useTagStore()
			resetUser()
			resetLockInfo()
			resetMenu()
			resetAuth()
			resetTags()
			if (goLogin) {
				await routerPush(PageEnum.BASE_LOGIN)
			}
		}
		return {
			userInfo,
			accessToken,
			userRoles,
			sessionTimeout,
			lastUpdateTime,
			setAccessToken,
			setRoles,
			setUserInfo,
			setSessionTimeout,
			resetUser,
			login,
			getUserInfoAction,
			afterLoginAction,
			logout
		}
	},
	{
		persist: true
	}
)
// 在组合式setup之外使用
export function useUserStoreWithout() {
	return useUserStore(pinia)
}
